//
//  NSObject+HYExtension.m
//  Object-CPlayGround
//
//  Created by 韩丛旸 on 16/8/14.
//  Copyright © 2016年 韩丛旸. All rights reserved.
//

#import "NSObject+HYExtension.h"
#import <objc/runtime.h>

@implementation NSObject (HYExtension)

static NSArray *propertiesArray;
static NSArray *ocPropertiesArray;
static NSDictionary *propertiesDictionary;

- (NSMutableDictionary *)hy_printModelAllProperties
{
    if ([self isKindOfClass:[NSDictionary class]]) return (NSMutableDictionary *)self.mutableCopy;
    if ([self isKindOfClass:[NSMutableDictionary class]]) return (NSMutableDictionary *)self.mutableCopy;
    if ([self isKindOfClass:[NSArray class]]) return @{@"NSArray":(NSArray *)self}.mutableCopy;
    if ([self isKindOfClass:[NSMutableArray class]]) return @{@"NSArray":(NSMutableArray *)self}.mutableCopy;
    
    
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];

    if (ocPropertiesArray == nil)
    {
        ocPropertiesArray = @[
                              @"NSArray",
                              @"NSString",
                              @"NSDictionary",
                              @"NSMutableArray",
                              @"NSMutableDictionary",
                              ];
    }

    if (propertiesArray == nil)
    {
        propertiesArray = @[
                            //------OC------
                            @"NSArray",
                            @"NSString",
                            @"NSDictionary",
                            @"NSMutableArray",
                            @"NSMutableDictionary",
                            @"Q",// NSUInteger
                            @"q",// NSInteger
                            @"B",// BOOL


                            //------C------
                            @"i",// Int
                            @"s",// Short
                            @"f",// Float
                            @"d",// Double
                            @"l",// Long
                            @"q",// LongLong
                            @"c",// Char or Bool
                            @"b",// Bool
                            @"*",// Pointer

                            //------Runtime------
                            @"^{objc_ivar=}",// Ivar
                            @"^{objc_method=}",// Method
                            @"@?",// Block
                            @"#",// Class
                            @":",// SEL
                            @"@",// Id
                            ];
    }

    if (propertiesDictionary == nil) {
        propertiesDictionary =  @{
                                  //------OC------
                                  @"NSArray":@"NSArray",
                                  @"NSString":@"NSString",
                                  @"NSDictionary":@"NSDictionary",
                                  @"NSMutableArray":@"NSMutableArray",
                                  @"NSMutableDictionary":@"NSMutableDictionary",
                                  @"Q":@"NSUInteger",// NSUInteger
                                  @"q":@"NSInteger",// NSInteger && LongLong
                                  @"B":@"BOOL",// BOOL

                                  //------C------
                                  @"i":@"Int",// Int
                                  @"s":@"Short",// Short
                                  @"f":@"Float",// Float
                                  @"d":@"Double",// Double
                                  @"l":@"Long",// Long
                                  @"c":@"Char or Bool",// Char or Bool
                                  @"b":@"Bool",// Bool
                                  @"*":@"Pointer",// Pointer

                                  //------Runtime------
                                  @"^{objc_ivar=}":@"Ivar",// Ivar
                                  @"^{objc_method=}":@"Method",// Method
                                  @"@?":@"Block",// Block
                                  @"#":@"Class",// Class
                                  @":":@"SEL",// SEL
                                  @"@":@"Id",// Id
                                  };

    }
    unsigned int count;

    objc_property_t *properties = class_copyPropertyList([self class], &count);

    for (int i = 0; i < count; i++) {
        objc_property_t property = properties[i];

        const char *cName = property_getName(property);
        const char *cAttribute = property_getAttributes(property);

        NSMutableString *name = [NSMutableString stringWithCString:cName encoding:NSUTF8StringEncoding];
        NSMutableString *attribute = [NSMutableString stringWithCString:cAttribute encoding:NSUTF8StringEncoding];

        NSArray *attributeArray = [attribute componentsSeparatedByString:@","];

        NSMutableString *attributeType = [[NSMutableString alloc] initWithString:(NSString *)attributeArray[0]];

        NSMutableString *attributeName = [[NSMutableString alloc] initWithString:(NSString *)[attributeArray lastObject]];

        attributeName = [attributeName substringFromIndex:2].mutableCopy;
        [attributeName insertString:@"_" atIndex:0];

        NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"T@\""];
        attributeType = [attributeType stringByTrimmingCharactersInSet:set].mutableCopy;

//        name = [NSString stringWithFormat:@"(type:%@ - propertyname:%@)", propertiesDictionary[attributeType]?:attributeType, attributeName].mutableCopy;
        name = [NSString stringWithFormat:@"%@", attributeName].mutableCopy;


        // 自定义NSObject对象

        id  value = [self valueForKey:attributeName];

        if (![propertiesArray containsObject:attributeType] && [value isKindOfClass:[NSObject class]])
        {
            NSMutableDictionary *dictionary = [value hy_printModelAllProperties];
            [dic addEntriesFromDictionary:@{name:dictionary}];
        }
        else if([propertiesArray containsObject:attributeType] && ![ocPropertiesArray containsObject:attributeType])
        {
            NSString *v;
            if ([attributeType isEqualToString:@"B"])
            {
                v = value?@"YES":@"NO";
            }
            else
            {
                v = [NSString stringWithFormat:@"%@", value];
            }

            [dic addEntriesFromDictionary:@{name:v}];

        }
        else
        {
            [dic addEntriesFromDictionary:@{name:value?:@""}];
        }

    }
    return dic;

}


@end
